home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / cagd_lib / cagd_tkn.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  8.8 KB  |  281 lines

  1. /******************************************************************************
  2. * Bzr-Read.c - Bezier curves handling routines - read from file.          *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Mar. 90.                          *
  5. ******************************************************************************/
  6.  
  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include "cagd_loc.h"
  11. #include "irit_soc.h"
  12.  
  13. #define UNGET_STACK_SIZE    3
  14. #define ZERO_NUM_EPSILON    1e-15
  15.  
  16. int _CagdGlblLineCount = 1;         /* Used to locate errors in input file. */
  17.  
  18. static int
  19.     GlblUnGetChar = 0,
  20.     GlblReadSocket = FALSE,                  /* If TRUE - read from socket. */
  21.     GlblTknStackSize = 0;              /* Used by parser, to unget token. */
  22. static char
  23.     GlblStringToken[UNGET_STACK_SIZE][LINE_LEN],    /* Save unget tokens.*/
  24.     CagdFloatFormat[LINE_LEN] =          /* Floating point printing format. */
  25. #ifdef DOUBLE
  26.     "%-8.6lg";
  27. #else
  28.     "%-8.6g";
  29. #endif /* DOUBLE */
  30.  
  31. static void InputUnGetC(char c);
  32. static char InputGetC(FILE *f);
  33. static int InputEOF(FILE *f);
  34. static void GetStringToken(FILE *f, char *StringToken);
  35.  
  36. /*****************************************************************************
  37. * Routine to read from input file f the    following [ATTR ...] [ATTR ...].     *
  38. * Note the '[' was allready read.                         *
  39. * Current supported attributes: None.                         *
  40. * Returns NULL if O.k., otherwise string describing the error.             *
  41. *****************************************************************************/
  42. char *_CagdGetCurveAttributes(FILE *f)
  43. {
  44.     TokenNumType i;
  45.     char StringToken[LINE_LEN];
  46.  
  47.     do {
  48.     switch (_CagdGetToken(f, StringToken)) {
  49.         default:
  50.         while ((i = _CagdGetToken(f, StringToken)) !=
  51.                             TOKEN_CLOSE_PAREN &&
  52.                i != TOKEN_EOF);
  53.         if (i == TOKEN_EOF)
  54.             return "EOF detected in middle of attribute.";
  55.         break;
  56.     }
  57.     }
  58.     while (_CagdGetToken(f, StringToken) == TOKEN_OPEN_PAREN);
  59.  
  60.     _CagdUnGetToken(StringToken);
  61.  
  62.     return NULL;
  63. }
  64.  
  65. /*****************************************************************************
  66. * Routine to read from input file f the    following [ATTR ...] [ATTR ...].     *
  67. * Note the '[' was allready read.                         *
  68. * Current supported attributes: None.                         *
  69. * Returns NULL if O.k., otherwise string describing the error.             *
  70. *****************************************************************************/
  71. char *_CagdGetSurfaceAttributes(FILE *f)
  72. {
  73.     TokenNumType i;
  74.     char StringToken[LINE_LEN];
  75.  
  76.     do {
  77.     switch (_CagdGetToken(f, StringToken)) {
  78.         default:
  79.         while ((i = _CagdGetToken(f, StringToken)) !=
  80.                             TOKEN_CLOSE_PAREN &&
  81.                i != TOKEN_EOF);
  82.         if (i == TOKEN_EOF)
  83.             return "EOF detected in middle of attribute.";
  84.         break;
  85.     }
  86.     }
  87.     while (_CagdGetToken(f, StringToken) == TOKEN_OPEN_PAREN);
  88.  
  89.     _CagdUnGetToken(StringToken);
  90.  
  91.     return NULL;
  92. }
  93.  
  94. /*****************************************************************************
  95. *   Routine to unget a single character from input stream.             *
  96. *****************************************************************************/
  97. static void InputUnGetC(char c)
  98. {
  99.     GlblUnGetChar = c;
  100. }
  101.  
  102. /*****************************************************************************
  103. *   Routine to get a single character from input stream.             *
  104. * If input returns EOF wait until new inputs arrive (can happen if reading   *
  105. * from a non io blocked socket).                         *
  106. *****************************************************************************/
  107. static char InputGetC(FILE *f)
  108. {
  109.     char c;
  110.  
  111.     do {
  112.     if (GlblUnGetChar) {
  113.         c = GlblUnGetChar;
  114.  
  115.         GlblUnGetChar = 0;
  116.     }
  117.     else if (GlblReadSocket)
  118.         c = SocClientReadCharNonBlock();
  119.     else
  120.         c = getc(f);
  121.  
  122.     if (c == (char) EOF)
  123.         IritSleep(10);
  124.     }
  125.     while (c == (char) EOF);
  126.  
  127.     return c;
  128. }
  129.  
  130. /*****************************************************************************
  131. *   Routine to test for EOF condition in input stream.                 *
  132. *****************************************************************************/
  133. static int InputEOF(FILE *f)
  134. {
  135.     if (GlblReadSocket)
  136.     return FALSE;
  137.     else
  138.     return feof(f);
  139. }
  140.  
  141. /******************************************************************************
  142. *   Routine to unget one token (on stack of UNGET_STACK_SIZE levels!)          *
  143. ******************************************************************************/
  144. void _CagdUnGetToken(char *StringToken)
  145. {
  146.     if (GlblTknStackSize >= UNGET_STACK_SIZE)
  147.     FATAL_ERROR(CAGD_ERR_PARSER_STACK_OV);
  148.  
  149.     strcpy(GlblStringToken[GlblTknStackSize++], StringToken);
  150. }
  151.  
  152. /******************************************************************************
  153. *   Routine to get the next token out of the input file    f.              *
  154. * Returns the next token found,    as StringToken.                      *
  155. * Note:    StringToken must be allocated before calling this routine!          *
  156. ******************************************************************************/
  157. static void GetStringToken(FILE *f, char *StringToken)
  158. {
  159.     int    Len;
  160.     char *LocalStringToken,
  161.     c = 0;
  162.  
  163.     if (GlblTknStackSize) {               /* Get first the unget token. */
  164.     strcpy(StringToken, GlblStringToken[--GlblTknStackSize]);
  165.     return;
  166.     }
  167.  
  168.     /* skip white spaces and comments: */
  169.     while (!InputEOF(f) &&
  170.        ((c = InputGetC(f)) == ' ' || c == '\t' || c == '\n' || c == '#')) {
  171.         /* Skip a comment if encounter one. */
  172.     if (c == '#')
  173.         while (!InputEOF(f) && c != '\n')
  174.         c = InputGetC(f);
  175.     if (c == '\n')
  176.          _CagdGlblLineCount++;             /* Count the lines. */
  177.     }
  178.  
  179.     LocalStringToken = StringToken;
  180.     if (c == '[')              /* Its a token by itself so return it. */
  181.     *LocalStringToken++ = c;          /* Copy the token into string. */
  182.     else {
  183.     if (!InputEOF(f))
  184.         do
  185.         *LocalStringToken++ = c;      /* Copy the token into string. */
  186.         while ((!InputEOF(f)) &&
  187.            ((c = InputGetC(f)) != ' ') && (c != '\t') && (c != '\n'));
  188.     if (c == '\n')
  189.         InputUnGetC(c);         /* Save it to be counted next time. */
  190.     }
  191.     *LocalStringToken =    0;                     /* Put eos. */
  192.  
  193.     /* The following handles the spacial case were we have XXXX] - we must   */
  194.     /* split it    into two token XXXX and    ], UnGetToken(']') and return XXXX:  */
  195.     if ((StringToken[Len = strlen(StringToken)-1] == ']') && (Len > 0))    {
  196.     /* Return CloseParen */
  197.     _CagdUnGetToken(&StringToken[Len]);             /* Save next token. */
  198.     StringToken[Len] = 0;            /* Set end of string on "]". */
  199.     }
  200. }
  201.  
  202. /******************************************************************************
  203. *   Routine to get the next token out of the input file    f as token number.    *
  204. * Returns the next token number    found, with numeric result in NumericToken    *
  205. * if TokenType is TOKEN_NUMBER.                              *
  206. * Note:    StringToken must be allocated before calling this routine!          *
  207. ******************************************************************************/
  208. TokenNumType _CagdGetToken(FILE *f, char *StringToken)
  209. {
  210.     GetStringToken(f, StringToken);
  211.  
  212.     if (InputEOF(f))
  213.     return TOKEN_EOF;
  214.  
  215.     if (!strcmp(StringToken, "["))
  216.     return TOKEN_OPEN_PAREN;
  217.     if (!strcmp(StringToken, "]"))
  218.     return TOKEN_CLOSE_PAREN;
  219.  
  220.     if (!strcmp(StringToken, "BEZIER"))
  221.     return TOKEN_BEZIER;
  222.     if (!strcmp(StringToken, "BSPLINE"))
  223.     return TOKEN_BSPLINE;
  224.     if (!strcmp(StringToken, "POWER"))
  225.     return TOKEN_POWER;
  226.  
  227.     if (!strcmp(StringToken, "CURVE"))
  228.     return TOKEN_CURVE;
  229.     if (!strcmp(StringToken, "SURFACE"))
  230.     return TOKEN_SURFACE;
  231.  
  232.     if (!strcmp(StringToken, "PTYPE"))
  233.     return TOKEN_PTYPE;
  234.     if (!strcmp(StringToken, "NUMPTS"))
  235.     return TOKEN_NUM_PTS;
  236.     if (!strcmp(StringToken, "ORDER"))
  237.     return TOKEN_ORDER;
  238.  
  239.     if (!strcmp(StringToken, "KV"))
  240.     return TOKEN_KV;
  241.  
  242.     return TOKEN_OTHER;                  /* Must be number or name. */
  243. }
  244.  
  245. /*****************************************************************************
  246. *  Routine to request reading from a socket (if non zero) instead of a file. *
  247. *****************************************************************************/
  248. void CagdReadSocket(int ReadSocket)
  249. {
  250.     GlblReadSocket = ReadSocket;
  251. }
  252.  
  253. /*****************************************************************************
  254. * Set the floating point numbers printing format.                 *
  255. *****************************************************************************/
  256. void CagdSetFloatFormat(char *FloatFormat)
  257. {
  258.     strncpy(CagdFloatFormat, FloatFormat, LINE_LEN - 1);
  259. }
  260.  
  261. /*****************************************************************************
  262. * Convert a real number into a string.                         *
  263. *****************************************************************************/
  264. char *_CagdReal2Str(CagdRType R)
  265. {
  266.     static char Buffer[LINE_LEN];
  267.     int j;
  268.  
  269.     if (ABS(R) < ZERO_NUM_EPSILON)
  270.     R = 0.0;
  271.  
  272.     sprintf(Buffer, CagdFloatFormat, R);
  273.  
  274.     for (j = strlen(Buffer) - 1; Buffer[j] == ' ' && j > 0; j--);
  275.     if (strchr(Buffer, '.') != NULL)
  276.     for (; Buffer[j] == '0' && j > 0; j--);
  277.     Buffer[j+1] = 0;
  278.  
  279.     return Buffer;
  280. }
  281.